home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / ucbmail / dateparse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-03-26  |  6.6 KB  |  336 lines

  1. /*
  2.  * We borrow this from MMDF's msg.
  3.  */
  4. /*
  5.  *            M S G 6 . C
  6.  *
  7.  * Functions -
  8.  *    smtpdate    Converts RFC822 date string to UNIX long
  9.  *    sunday
  10.  *    eatwhite    Returns first nonwhitespace char in string
  11.  *    match
  12.  *    makedate    Convert UNIX time to string
  13.  *
  14.  *
  15.  *        R E V I S I O N   H I S T O R Y
  16.  *
  17.  *    07/08/84  HAW    Created this module for time stamp processing.
  18.  *            Most routines in this module were written
  19.  *            by Ron Natelie.
  20.  *
  21.  */
  22. #include "./rcv.h"
  23. #include <ctype.h>
  24.  
  25. extern    long    timezone;
  26.  
  27. /*
  28.  *  S M T P _ D A T E
  29.  *
  30.  *  Take an RFC822 (more or less) date string cp and convert it to
  31.  *  unix time.  Allows a variety of illegal formats commonly in use.
  32.  *
  33.  */
  34.  
  35. #define    SPACE    ' '
  36. #define    HTAB    '\t'
  37.  
  38. /*
  39.  *  Matchtab structure.
  40.  *  Used by match routine.
  41.  */
  42. struct    match_tab  {
  43.     char    *t_string;        /*  String to match, NOSTR for last.  */
  44.     int    t_val;            /*  Value to be returned.  */
  45. };
  46.  
  47. /*
  48.  *  Month tab matches month names to number.
  49.  */
  50. struct    match_tab    month_tab[]  =  {
  51.     "jan", 1,    "feb", 2,    "mar", 3,    "apr", 4,
  52.     "may", 5,    "jun", 6,    "jul", 7,    "aug", 8,
  53.     "sep", 9,    "oct", 10,    "nov", 11,    "dec", 12,
  54.     NOSTR, 0
  55. };
  56.     
  57. #define    H(x)    ( (x)*60*60)
  58. struct    match_tab    zone_tab[] = {
  59.     "ut", 0,    "gmt", 0,    "est", H(-5),    "edt", H(-4),
  60.     "cst", H(-6),    "cdt", H(-5),    "mst", H(-7),    "mdt", H(-6),
  61.     "pst", H(-8),    "pdt", H(-7),    "z", 0,
  62.     "a", H(-1),    "b", H(-2),    "c", H(-3),    "d", H(-4),
  63.     "e", H(-5),    "f", H(-6),    "g", H(-7),    "h", H(-8),
  64.     "i", H(-9),    "k", H(-10),    "l", H(-11),    "m", H(-12),
  65.     "n", H(1),    "o", H(2),    "p", H(3),    "q", H(4),
  66.     "r", H(5),    "s", H(6),    "t", H(7),    "u", H(8),
  67.     "v", H(9),    "w", H(10),    "x", H(11),    "y", H(12),
  68.     NOSTR, 1
  69. };
  70.  
  71. #define    dysize(A) (((A)%4) ? 365: 366)
  72. static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  73. extern char *index();
  74. extern char *eatwhite();
  75.  
  76. long
  77. smtpdate(cp)
  78.     register char    *cp;
  79. {
  80.     int    day, month, year, hours, minutes, seconds;
  81.     int    dayno;
  82.     long    tval;
  83.     int    i;
  84.     char    *dp;
  85.     time_t    zone;
  86. /*printf("S entry - date str: %s", cp); */
  87.     cp = eatwhite(cp);
  88.     dp = cp;
  89.  
  90.  
  91.     /*
  92.      *  Look for digit, supposed to be day of the month, skipping
  93.      *  over day of the week stuff.
  94.      */
  95.     while(1)  {
  96.         if(*cp == 0)  goto bad_date;
  97.         if(isdigit(*cp)) break;
  98.         cp++;
  99.     }
  100.  
  101.     day = atoi(cp);
  102. /*printf("S day: %d\n",day); */
  103.     /*  Skip digits and white space to get to month.  */
  104.  
  105.     while(isdigit(*cp)) cp++;
  106.     while( *cp == SPACE || *cp == HTAB || *cp == '-') cp++;
  107.  
  108.     month = match(month_tab, cp, 3);
  109.     if(month == 0)  {
  110.         /*  Hack here, look for ctime format.  */
  111.         day = atoi(&dp[8]);
  112.         month = match(month_tab, &dp[4], 3);
  113.         if(month == 0) goto bad_date;
  114.         year = atoi(&dp[20]);
  115.         hours = atoi(&dp[11]);
  116.         minutes = atoi(&dp[14]);
  117.         seconds = atoi(&dp[17]);
  118.         zone = -1;
  119. /*printf("S ctime for: y: %d m: %d d: %d h: %d m: %d s: %d\n",year,month,day,hours,minutes,seconds); */
  120.  
  121.     }
  122.     else  {
  123.         /*  Skip over to the year  */
  124.         while(1)  {
  125.             if(*cp == 0)  goto bad_date;
  126.             if(isdigit(*cp)) break;
  127.             cp++;
  128.         }
  129.         year = atoi(cp);
  130.  
  131.         while(isdigit(*cp)) cp++;
  132.  
  133.         while(*cp && !isdigit(*cp)) cp++;
  134.     
  135.  
  136.         /*  Hours, minutes, seconds  */
  137.         hours = atoi(cp);
  138.         if(hours > 60)  {
  139.             minutes = hours %100;
  140.             hours = hours/100;
  141.         }  else  {
  142.             cp = index(cp, ':');
  143.             if(cp == NOSTR) goto bad_date;
  144.             minutes = atoi(++cp);
  145.         }
  146.  
  147.         dp = index(cp, ':');
  148.         if(dp)  {
  149.             seconds = atoi(++dp);
  150.             cp = dp;
  151.         }
  152.         else    seconds = 0;
  153. /*printf("S hours: %d  mins: %d  secs: %d\n",hours,minutes,seconds); */
  154.         while(isdigit(*cp)) cp++;
  155.         cp = eatwhite(cp);
  156. /*printf("S Zone starts- str: %s",cp); */
  157.         if( (*cp == '+' || *cp == '-')  &&
  158.            isdigit(cp[1]) &&
  159.            isdigit(cp[2]) &&
  160.            isdigit(cp[3]) &&
  161.            isdigit(cp[4])
  162.         )  {
  163.             zone = atoi(cp+3) * 60L;
  164.             cp[3] = 0;
  165.             zone *= atoi(cp);
  166.         } else {
  167.             if( *cp == '+' || *cp == '-' )
  168.                 cp++;
  169.             dp = cp;
  170.             while(isalpha(*cp)) cp++;
  171.             *cp = 0;
  172.             zone = -match(zone_tab, dp, 0);
  173.         }
  174. /*printf("S zone: %d\n",zone); */
  175.     }
  176.     if(year < 1900) year += 1900;
  177.     if(month < 1 || month > 12)  goto bad_date;
  178.     if(day < 1 || day > 31) goto bad_date;
  179.     if(hours == 24)  {
  180.         hours = 0;
  181.         day++;
  182.     }
  183.     if(hours < 0 || hours > 23) goto bad_date;
  184.     if(minutes < 0 || minutes > 59) goto bad_date;
  185.     if(seconds < 0 || seconds > 59) goto bad_date;
  186.  
  187.     tval = 0;
  188.     dayno = 0;
  189.     for(i = 1970; i < year; i++)
  190.         tval += dysize(i);
  191.  
  192.     if(dysize(year) == 366  && month >= 3)
  193.         dayno += 1;
  194.     while(--month) dayno += dmsize[month-1];
  195.     tval += dayno;
  196.     tval += day-1;
  197.     tval *= 24;
  198.     tval += hours;
  199.     tval *= 60;
  200.     tval += minutes;
  201.     tval *= 60;
  202.     tval += seconds;
  203.     if(zone == -1)  {
  204.         int beg, end;
  205.         beg = sunday(119, year);
  206.         end = sunday(303, year);
  207. /*printf("S beg: %d  end: %d\n",beg,end); */
  208.         zone = gettimezone();
  209. /*printf("S timezone: %d  daylight: %d: dayno: %d\n",timezone,DAYLIGHT,dayno); */
  210.         if(DAYLIGHT &&
  211.             (dayno>beg || (dayno==beg && hours >=2)) &&
  212.             (dayno<end || (dayno==end && hours <1)))
  213.         {
  214. /*printf("S changing zone for DAYLIGHT\n"); */
  215.             zone -= 60*60;
  216.         }
  217.     }
  218. /*printf("S before zone: %s",ctime(&tval)); */
  219.     tval += zone;
  220. /*printf("S after zone: %s\n",ctime(&tval)); */
  221.     return tval;
  222.  
  223. bad_date:
  224.     return -1L;
  225. }
  226.  
  227. #ifdef SYS5
  228. time_t
  229. gettimezone()
  230. {
  231.     extern long timezone;
  232.     static int set = 0;
  233.  
  234.     if (!set) {
  235.         tzset();
  236.         set = 1;
  237.     }
  238.     return((time_t)timezone);
  239. }
  240. #else
  241. #include <sys/timeb.h>
  242.  
  243. time_t
  244. gettimezone()
  245. {
  246.     static struct timeb tb;
  247.     static int set = 0;
  248.  
  249.     if (!set) {
  250.         ftime(&tb);
  251.         set = 1;
  252.     }
  253.     return((time_t)tb.timezone);
  254. }
  255. #endif
  256.  
  257. static int
  258. sunday(d, year)
  259. {
  260.     int i;
  261.     int    pdays = 0;
  262.  
  263.     for(i = 1970; i < year; i++)
  264.         pdays += dysize(i);
  265.     if(d >= 58 && dysize(year) == 366) d++;
  266.     pdays = (pdays - 3) % 7;    /*  Day of week, day 0 was thurs  */
  267.     if(pdays) d += 7-pdays;
  268.     return d;
  269. }
  270. /*
  271.  *  E A T W H I T E
  272.  *
  273.  *  An old favorite, returns the first non whitespace in the string.
  274.  */
  275. char *
  276. eatwhite(cp)
  277.     register char *cp;
  278. {
  279.     while(*cp == SPACE || *cp == HTAB) cp++;
  280.     return cp;
  281. }
  282.  
  283. match(tab, string, size)
  284.     register struct    match_tab    *tab;
  285.     char    *string;
  286.     int    size;
  287. {
  288.     register char *cp, *str;
  289.     char    *bufend;
  290.     char    buffer[512];
  291.     
  292.     bufend = &buffer[ (size == 0) ? 512 : size];
  293.     for(cp = buffer, str = string; cp < bufend; cp++, str++)  {
  294.         if(isupper(*str)) *cp = tolower(*str);
  295.         else    *cp = *str;
  296.         if(*cp == 0) break;
  297.     }
  298.  
  299.     while(tab->t_string != NOSTR)  {
  300.         if(size)  {
  301.             if(strncmp(buffer,tab->t_string, size) == 0)
  302.                 break;
  303.         }  else  {
  304.             if(strcmp(buffer, tab->t_string) == 0)
  305.                 break;
  306.         }
  307.         tab++;
  308.     }
  309.     return tab->t_val;
  310. }
  311.  
  312. /*
  313.  *            M A K E D A T E
  314.  *
  315.  * Convert UNIX date to string (DD MMM YY)
  316.  */
  317. makedate( date, dest )
  318. long    *date;
  319. char    *dest;
  320. {
  321.     char *cp;
  322.     char *ctime( );
  323.  
  324.     cp = ctime( date );
  325.      *dest++ = cp[8];
  326.      *dest++ = cp[9];
  327.      *dest++ = ' ';
  328.      *dest++ = cp[4];
  329.      *dest++ = cp[5];
  330.      *dest++ = cp[6];
  331.      *dest++ = ' ';
  332.      *dest++ = cp[22];
  333.      *dest++ = cp[23];
  334.  
  335. }
  336.